Программирование сетевых приложений

Базовые конструкции и основные элементы языка C++ и Qt

Программирование сетевых приложений

Содержание лекции

  • Переменные и типы данных
  • Преобразование и приведение типов
  • Динамическая инициализация
  • Область действия и время жизни переменных
  • Циклы и логические конструкции
  • Массивы и строки
  • Особенности Qt-типов
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Переменные и типы данных в C++

// Целочисленные типы
int counter = 42;           // 32-битное целое
long long bigNumber = 1234567890LL;  // 64-битное целое
unsigned int positive = 100;         // Беззнаковое целое

// Типы с плавающей точкой
float pi = 3.14f;           // 32-битное число
double precise = 3.14159265359;     // 64-битное число

// Символьные типы
char symbol = 'A';          // Один символ
wchar_t wideChar = L'Б';    // Широкий символ
char16_t utf16 = u'ю';      // UTF-16 символ
char32_t utf32 = U'😀';     // UTF-32 символ

// Логический тип
bool isConnected = true;    // true или false
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Квалификаторы типов

// Квалификатор const - неизменяемость
const int MAX_CONNECTIONS = 100;
const double PI = 3.14159;

// Квалификатор constexpr - константа времени компиляции
constexpr int BUFFER_SIZE = 1024;
constexpr double EULER_NUMBER = 2.71828;

// Квалификатор volatile - запрет оптимизации
volatile bool dataReady = false;  // Может измениться вне программы

// Квалификатор mutable - возможность изменения в const-методах
class NetworkBuffer {
private:
    mutable int accessCount = 0;
    
public:
    void process() const {
        accessCount++;  // Допустимо благодаря mutable
    }
};
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Пользовательские типы данных

// Перечисления (enum)
enum ConnectionState {
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    ERROR_STATE
};

// Перечисления с областью видимости (enum class)
enum class ProtocolType {
    TCP,
    UDP,
    HTTP,
    WebSocket
};

// Структуры (struct)
struct NetworkPacket {
    int packetId;
    std::string data;
    time_t timestamp;
};

// Объединения (union)
union DataValue {
    int integer;
    float floating;
    char string[8];
};
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Преобразование типов в C++

Неявное преобразование (автоматическое)

int x = 10;
double y = x;           // Неявное преобразование int -> double
char c = 'A';
int code = c;           // Неявное преобразование char -> int

// Потеря точности
double precise = 3.14159;
int truncated = precise;  // 3 (дробная часть отбрасывается)
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Явное преобразование (приведение типов)

// Старый стиль C
int oldStyle = (int)3.14;

// Новый стиль C++
double value = 3.14;
int cast1 = static_cast<int>(value);        // Безопасное приведение
int* ptr = nullptr;
void* voidPtr = reinterpret_cast<void*>(ptr);  // Приведение указателей

// Приведение const
const int constValue = 42;
int* nonConst = const_cast<int*>(&constValue);  // Удаление const

// Приведение с проверкой (для полиморфных типов)
class Base { virtual void foo() {} };
class Derived : public Base { void bar() {} };

Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base);  // Проверка времени выполнения
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Расширение типов (Type Promotion)

// Автоматическое расширение в выражениях
short s1 = 10, s2 = 20;
int result = s1 + s2;    // short расширяется до int

// Правила расширения
char c = 'A';
int i = 50;
float f = 1.5f;

auto sum = c + i + f;    // char -> int -> float

// Расширение в функциях
void processValue(int value) { /* ... */ }

short shortValue = 100;
processValue(shortValue);  // Автоматическое расширение short -> int
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Динамическая инициализация

Инициализация переменных

// Прямая инициализация
int port(8080);
std::string server("localhost");

// Список инициализации (C++11)
int bufferSize{4096};
double timeout{30.5};

// Автоматический вывод типа (C++11)
auto portNumber = 8080;        // int
auto serverName = "localhost"; // const char*
auto piValue = 3.14159;        // double

// Инициализация nullptr (C++11)
int* pointer = nullptr;        // Современный способ обозначения нулевого указателя
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Инициализация в Qt

#include <QString>
#include <QVector>
#include <QMap>

// Инициализация QString
QString message = "Hello, Qt!";
QString emptyString;  // Пустая строка

// Инициализация контейнеров Qt
QVector<int> numbers = {1, 2, 3, 4, 5};  // Список инициализации
QMap<QString, int> settings = {
    {"timeout", 30},
    {"retries", 3},
    {"port", 8080}
};

// Инициализация сетевых классов Qt
#include <QHostAddress>
QHostAddress localHost("127.0.0.1");
QHostAddress anyAddress = QHostAddress::Any;
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Область действия переменных (Scope)

Глобальная область видимости

// Глобальные переменные
int globalConnectionCount = 0;
const int MAX_BUFFER_SIZE = 4096;

// Пространство имен
namespace NetworkConfig {
    const std::string DEFAULT_HOST = "localhost";
    const int DEFAULT_PORT = 8080;
}

void function() {
    std::cout << NetworkConfig::DEFAULT_HOST << std::endl;
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Локальная область видимости

void processData() {
    int localCounter = 0;  // Локальная переменная
    
    if (true) {
        int blockScoped = 42;  // Область видимости - блок if
        localCounter = blockScoped;
    }
    // blockScoped недоступен здесь
    
    for (int i = 0; i < 10; i++) {
        // i доступен только внутри цикла
        localCounter += i;
    }
    // i недоступен здесь
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Время жизни переменных (Lifetime)

Автоматическое время жизни

void function() {
    int autoVariable = 10;  // Создается при входе в функцию
    // ... использование переменной
}  // Уничтожается при выходе из функции
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Статическое время жизни

void counterFunction() {
    static int callCount = 0;  // Создается один раз
    callCount++;
    std::cout << "Function called " << callCount << " times" << std::endl;
}

class NetworkServer {
private:
    static int instanceCount;  // Статический член класса
    // ...
};

// Определение вне класса
int NetworkServer::instanceCount = 0;
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Динамическое время жизни

void dynamicExample() {
    // Создание в куче (heap)
    int* dynamicArray = new int[100];
    
    // Использование массива
    for (int i = 0; i < 100; i++) {
        dynamicArray[i] = i * i;
    }
    
    // Освобождение памяти
    delete[] dynamicArray;
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Условные конструкции

Оператор if-else

int checkConnectionStatus(int port) {
    if (port < 0 || port > 65535) {
        return -1;  // Неверный порт
    } else if (port < 1024) {
        return 0;   // Системный порт
    } else {
        return 1;   // Пользовательский порт
    }
}

// Тернарный оператор
std::string getStatus(bool isConnected) {
    return isConnected ? "Connected" : "Disconnected";
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Оператор switch

std::string getProtocolName(int protocol) {
    switch (protocol) {
        case 6:
            return "TCP";
        case 17:
            return "UDP";
        case 80:
            return "HTTP";
        case 443:
            return "HTTPS";
        default:
            return "Unknown";
    }
}

// Switch с несколькими case
std::string getServiceType(int port) {
    switch (port) {
        case 21:
        case 22:
        case 23:
            return "Remote Access";
        case 25:
        case 587:
            return "Email";
        case 80:
        case 443:
        case 8080:
            return "Web Service";
        default:
            return "Other";
    }
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Циклы в C++

Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Цикл for

// Классический for
for (int i = 0; i < 10; i++) {
    std::cout << "Iteration: " << i << std::endl;
}

// For с несколькими переменными
for (int i = 0, j = 10; i < j; i++, j--) {
    std::cout << i << " " << j << std::endl;
}

// Бесконечный цикл
for (;;) {
    if (condition) break;
    // ...
}

// Диапазонный for (C++11)
std::vector<int> ports = {80, 443, 8080, 3000};
for (int port : ports) {
    std::cout << "Port: " << port << std::endl;
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Цикл while

// Предусловный цикл
int attempts = 0;
while (attempts < 3 && !isConnected) {
    connectToServer();
    attempts++;
}

// Бесконечный цикл с условием выхода
while (true) {
    std::string input = getUserInput();
    if (input == "exit") break;
    processCommand(input);
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Цикл do-while

// Постусловный цикл
char choice;
do {
    std::cout << "Continue? (y/n): ";
    std::cin >> choice;
} while (choice == 'y' || choice == 'Y');

// Меню с гарантированным первым выполнением
int option;
do {
    showMenu();
    std::cin >> option;
    processMenuOption(option);
} while (option != 0);
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Управление циклами

// Оператор break - выход из цикла
for (int port = 1; port <= 65535; port++) {
    if (isPortOpen(port)) {
        std::cout << "Found open port: " << port << std::endl;
        break;  // Выход при первом найденном открытом порте
    }
}

// Оператор continue - переход к следующей итерации
std::vector<int> ports = {21, 22, 80, 443, 8080, 3306};
for (int port : ports) {
    if (isPortReserved(port)) {
        continue;  // Пропустить зарезервированные порты
    }
    scanPort(port);
}

// Метки для выхода из вложенных циклов
outerLoop:
for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (i * j > 50) {
            break outerLoop;  // Выход из обоих циклов
        }
    }
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Массивы в C++

Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Статические массивы

// Одномерные массивы
int ports[5] = {80, 443, 8080, 3000, 9000};
char message[] = "Hello, Network!";  // Автоматический размер

// Двумерные массивы
int matrix[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// Массивы без инициализации
int buffer[1024];  // Содержит мусор
int zeros[256] = {0};  // Все элементы = 0
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Работа с массивами

// Доступ к элементам
int firstPort = ports[0];      // 80
int lastPort = ports[4];       // 9000

// Изменение элементов
ports[2] = 8888;  // Заменить 8080 на 8888

// Перебор массива
for (int i = 0; i < 5; i++) {
    std::cout << "Port " << i << ": " << ports[i] << std::endl;
}

// Ошибка: выход за границы
// int invalid = ports[10];  // Неопределенное поведение!
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Динамические массивы

// Создание динамического массива
int* dynamicPorts = new int[10];

// Инициализация
for (int i = 0; i < 10; i++) {
    dynamicPorts[i] = 1000 + i * 100;
}

// Использование
std::cout << "Port 5: " << dynamicPorts[5] << std::endl;  // 1500

// Освобождение памяти
delete[] dynamicPorts;

// Современный подход с умными указателями
#include <memory>
std::unique_ptr<int[]> smartPorts(new int[10]);
smartPorts[0] = 8080;  // Автоматическое освобождение памяти
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Строки в C++

Базовые конструкции и основные элементы языка
Программирование сетевых приложений

C-style строки

// Создание C-строк
char cString1[] = "Network";
char cString2[20] = "Programming";
const char* cString3 = "C++";

// Работа с C-строками
#include <cstring>
char buffer[50];
strcpy(buffer, "Hello ");
strcat(buffer, "World");
int length = strlen(buffer);

// Сравнение
if (strcmp(cString1, cString2) == 0) {
    std::cout << "Strings are equal" << std::endl;
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

C++ строки (std::string)

#include <string>

// Создание строк
std::string str1 = "Network";
std::string str2("Programming");
std::string str3 = str1 + " " + str2;  // "Network Programming"

// Методы строк
int len = str1.length();          // Длина
char first = str1[0];            // Первый символ
std::string sub = str1.substr(0, 4);  // "Netw"

// Поиск и замена
size_t pos = str3.find("Prog");
if (pos != std::string::npos) {
    str3.replace(pos, 4, "Development");
}

// Преобразование чисел
int port = 8080;
std::string portStr = std::to_string(port);
int portNum = std::stoi(portStr);
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

QString в Qt

#include <QString>
#include <QDebug>

// Создание QString
QString qtString1 = "Qt Network";
QString qtString2 = QString("Programming");
QString qtString3 = qtString1 + " " + qtString2;

// Преобразования
std::string stdStr = qtString3.toStdString();
const char* cStr = qtString3.toLocal8Bit().constData();

// Форматирование (аналог sprintf)
QString formatted = QString("Server %1:%2 is %3")
                   .arg("localhost")
                   .arg(8080)
                   .arg("running");

// Работа с Unicode
QString unicode = QString::fromUtf8("Привет, мир!");
QString fromStd = QString::fromStdString("C++ string");

// Полезные методы
bool startsWith = qtString1.startsWith("Qt");
bool endsWith = qtString1.endsWith("Network");
QString upper = qtString1.toUpper();
QString lower = qtString1.toLower();
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Контейнеры Qt для массивов

#include <QVector>
#include <QList>
#include <QMap>
#include <QHash>

// QVector - динамический массив
QVector<int> ports;
ports.append(80);
ports.append(443);
ports << 8080 << 3000;  // Оператор <<

// Доступ к элементам
int first = ports.first();    // 80
int last = ports.last();      // 3000
int at2 = ports.at(2);        // 8080 (с проверкой границ)

// QList - список (оптимизирован для Qt)
QList<QString> protocols;
protocols << "TCP" << "UDP" << "HTTP";

// Поиск и удаление
int index = protocols.indexOf("UDP");
if (index != -1) {
    protocols.removeAt(index);
}

// QMap - ассоциативный массив
QMap<QString, int> portMap;
portMap["HTTP"] = 80;
portMap["HTTPS"] = 443;
portMap["FTP"] = 21;

int httpPort = portMap["HTTP"];  // 80
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Современные особенности C++11 и выше

// Автоматический вывод типа
auto port = 8080;                    // int
auto server = "localhost";           // const char*
auto config = NetworkConfig("srv", 80);  // NetworkConfig

// Универсальная инициализация
int ports[] = {80, 443, 8080};
std::vector<int> portsVec{80, 443, 8080};
std::map<std::string, int> settings{
    {"timeout", 30},
    {"retries", 3}
};

// nullptr вместо NULL
int* pointer = nullptr;  // Безопасный нулевой указатель

// Range-based for
std::vector<std::string> protocols = {"TCP", "UDP", "HTTP"};
for (const auto& proto : protocols) {
    std::cout << proto << std::endl;
}
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Заключение

Основные концепции:

  • Переменные и типы - фундамент любой программы
  • Преобразование типов - важно для предотвращения ошибок
  • Область видимости и время жизни - критичны для управления ресурсами
  • Циклы и условия - управление потоком выполнения
  • Массивы и строки - основы работы с данными
  • Qt-типы - расширение возможностей стандартных типов
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Рекомендации:

  • Используйте современные конструкции C++11+
  • Предпочитайте std::string и QString C-строкам
  • Используйте контейнеры Qt для удобства и безопасности
  • Следите за областью видимости переменных
  • Правильно управляйте временем жизни объектов
Базовые конструкции и основные элементы языка
Программирование сетевых приложений

Вопросы для самопроверки

  1. Чем отличаются const и constexpr?
  2. Какие существуют способы приведения типов в C++?
  3. В чем различие между std::string и QString?
  4. Как управлять временем жизни динамически выделенных объектов?
  5. Когда использовать QVector, а когда QList?
  6. Что такое области видимости и как они влияют на доступ к переменным?
  7. Какие преимущества дает использование диапазонных циклов?
  8. В чем различие между структурой и классом в C++?
Базовые конструкции и основные элементы языка